// DrawPolyline
/*
绘制线
 */
class DrawPolyline {
  constructor(arg) {
    this.viewer = arg
    this.Cesium = Cesium
    this.callback = arg.callback
    this._polyline = null // 活动线
    this._polylineLast = null // 最后一条线
    this._positions = [] // 活动点
    this._entities_point = [] // 脏数据
    this._entities_line = [] // 脏数据
    this._polylineData = null // 用于构造线数据
    this._totalLength = 0 // 长度
  }

  // 返回最后活动线
  get line() {
    return this._polylineLast
  }

  // 返回线数据用于加载线
  getData() {
    return this._polylineData
  }

  // 加载线
  loadPolyline(data) {
    var $this = this
    var polyline = this.viewer.entities.add({
      name: 'toolGraphics',
      polyline: {
        positions: data,
        show: true,
        material: $this.Cesium.Color.RED,
        width: 3,
        clampToGround: true
      }
    })
    return polyline
  }

  // 开始创建
  startCreate() {
    // 返回绘制的图形坐标
    return new Promise((resolve, reject) => {
      var $this = this
      this.handler = new this.Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas)

      this.handler.setInputAction(function (evt) {
        // 单机开始绘制
        // 屏幕坐标转地形上坐标
        var cartesian = $this.getCatesian3FromPX(evt.position)
        if ($this._positions.length == 0) {
          $this._positions.push(cartesian.clone())
        }
        $this._positions.push(cartesian)
        if ($this._positions.length > 2) {
          let t = Cesium.Cartesian3.distance($this._positions[$this._positions.length - 3], cartesian)
          $this._totalLength = Number((t / 1000 + $this._totalLength).toFixed(2))
          // $this._totalLength += $this.terrianDistance($this._positions[$this._positions.length - 3], cartesian, t)
          // $this._totalLength = parseFloat($this._totalLength.toFixed(2))
        }
        $this.createPoint(cartesian, $this._totalLength) // 绘制点
      }, $this.Cesium.ScreenSpaceEventType.LEFT_CLICK)

      this.handler.setInputAction(function (evt) {
        // 移动时绘制线
        if ($this._positions.length < 1) return
        var cartesian = $this.getCatesian3FromPX(evt.endPosition)
        if (!$this.Cesium.defined($this._polyline)) {
          $this._polyline = $this.createPolyline()
        }
        if ($this._polyline) {
          $this._positions.pop()
          $this._positions.push(cartesian)
        }
      }, $this.Cesium.ScreenSpaceEventType.MOUSE_MOVE)

      this.handler.setInputAction(async function (evt) {
        if (!$this._polyline) return
        var cartesian = $this.getCatesian3FromPX(evt.position)
        $this._positions.pop()
        $this._positions.push(cartesian)
        let t = Cesium.Cartesian3.distance($this._positions[$this._positions.length - 3], cartesian)
        $this._totalLength = Number((t / 1000 + $this._totalLength).toFixed(2))
        $this.createPoint(cartesian, $this._totalLength) // 绘制点
        $this._polylineData = $this._positions.concat()
        $this.viewer.entities.remove($this._polyline) // 移除
        $this._polyline = null
        $this._positions = []
        var line = $this.loadPolyline($this._polylineData) // 加载线
        $this._entities_line.push(line)
        $this._polylineLast = line
        if (typeof $this.callback === 'function') {
          $this.callback(line)
        }
        // 销毁实例
        $this.destroy()
        let zuobiao = await $this.getData() // 获取绘制直线后的坐标
        // console.log(zuobiao)
        resolve(zuobiao)
      }, $this.Cesium.ScreenSpaceEventType.RIGHT_CLICK)
    })
  }

  /**
   * 表面距离
   * @param start
   * @param end
   * @param t
   * @private
   */
  terrianDistance(start, end, t) {
    //  测地线（椭球上距离）
     let geodesic = new Cesium.EllipsoidGeodesic()
     let startGeodesic = Cesium.Cartographic.fromCartesian(start) //笛卡尔系转经纬度
     let endGeodesic = Cesium.Cartographic.fromCartesian(end)
     geodesic.setEndPoints(startGeodesic, endGeodesic)
     let lengthInMeters = geodesic.surfaceDistance / 1000
     return parseFloat(lengthInMeters)
    // var $this = this
    // let level = Math.ceil(Math.log10(t))
    // let count = level * 5
    // let lerp = []
    // let vertexLength = 0
    // //两个端点加上count个插值点
    // for (let i = 0; i <= count + 1; i++) {
    //   let pt = Cesium.Cartesian3.lerp(start, end, i / (count + 1), new Cesium.Cartesian3()) //插值点
    //   let samplePt = $this.viewer.scene.clampToHeight(pt) //高度采样点
    //   lerp.push(samplePt)
    // }
    // //计算折线长度
    // for (let j = 1; j < lerp.length; j++) {
    //   let left = lerp[j - 1]
    //   let right = lerp[j]
    //   let length = Cesium.Cartesian3.distance(left, right)
    //   vertexLength += length
    // }
    // vertexLength = vertexLength / 1000
    // return vertexLength
  }

  // 创建点
  createPoint(cartesian, length = 0) {
    var $this = this
    var point = this.viewer.entities.add({
      name: 'toolGraphics',
      position: cartesian,
      point: {
        pixelSize: 10,
        color: $this.Cesium.Color.YELLOW
      },
      label: {
        text: length + '千米',
        font: '18px Microsoft YaHei',
        fillColor: Cesium.Color.fromCssColorString('rgb(255, 255, 255)').withAlpha(1.5),
        verticalOrigin: Cesium.VerticalOrigin.CENTER,
        pixelOffset: new Cesium.Cartesian2(0, -25, 10),
        disableDepthTestDistance: 15000000,
        distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 500000)
      }
    })
    $this._entities_point.push(point)
    return point
  }

  // 创建线
  createPolyline() {
    var $this = this
    var polyline = this.viewer.entities.add({
      name: 'toolGraphics',
      polyline: {
        // 使用cesium的peoperty
        positions: new $this.Cesium.CallbackProperty(function () {
          return $this._positions
        }, false),
        show: true,
        material: $this.Cesium.Color.RED,
        width: 3,
        clampToGround: true
      }
    })
    $this._entities_line.push(polyline)
    return polyline
  }

  // 销毁
  destroy() {
    this.clear()
    if (this.handler) {
      this.handler.destroy()
      this.handler = null
    }
  }

  // 清空实体对象
  clear() {
    // for (var i = 0; i < this._entities_point.length; i++) {
    //   this.viewer.entities.remove(this._entities_point[i])
    // }
    // for (var i = 0; i < this._entities_line.length; i++) {
    //   this.viewer.entities.remove(this._entities_line[i])
    // }
    this._polyline = null
    this._positions = []
    this._entities_point = [] // 脏数据
    this._entities_line = [] // 脏数据
    this._polylineData = null // 用于构造线数据
    this._polylineLast = null
    this._totalLength = 0 // 长度
  }

  getCatesian3FromPX(px) {
    var cartesian
    var ray = this.viewer.camera.getPickRay(px)
    if (!ray) return null
    cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene)
    return cartesian
  }
}

export default DrawPolyline
